import json

from asgiref.sync import async_to_sync
from channels.exceptions import StopConsumer
from channels.generic.websocket import WebsocketConsumer
from channels.layers import get_channel_layer

from api.commands import command_dispatch
from api.commands.basic_command_runhandler import UserSite
from api.commands.interface import SendType
from framework.Singleton import Singleton


def send():
    channel_box = ChannelBox()
    channel_box.groupSend("inner", {"value": "群发完毕", "New": 2})


class ChannelBox(metaclass=Singleton):
    def __init__(self):
        self.channel_layer = get_channel_layer()

    def delete(self, connecthandler, group):
        async_to_sync(self.channel_layer.group_discard)(
            group if group is not None else "inner",
            connecthandler.channel_name
        )

    def add_group(self, connecthandler: WebsocketConsumer, group=None):
        """
        加入某个群
        :param group:
        :return:
        """
        handler = async_to_sync(self.channel_layer.group_add)
        handler(group if group is not None else "inner", connecthandler.channel_name)

    def groupSend(self, body=None, group=None):
        """
        群发
        :param group 群发组 默认是inner
        :param body
        :return:
        """
        if group is None: group = "inner"
        if body is None: body = "okay"

        if isinstance(body, dict):
            body = json.dumps(body, ensure_ascii=False)
        print("开始发送数据")
        async_to_sync(self.channel_layer.group_send)(
            group,
            {"body": body, "type": "chat.message"}
        )


class CodeRunner(WebsocketConsumer):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

        self.channelBox = ChannelBox()

    def websocket_connect(self, message):
        ...

        self.accept()
        print("新的加入")

        self.channelBox.add_group(self)

    def websocket_receive(self, message):
        command_body = message.get('text')
        print(message)
        # 解析命令的执行器
        commandDispath = command_dispatch(command=command_body)

        excetor = commandDispath.dispath()
        if excetor is None:
            self.send("该消息无法被处理")
            return
        # 利用执行器进行代码的执行
        return_value = excetor.run()
        return_message = return_value.messgae
        return_type = return_value.send_type

        return_message["messge_mod"] = return_value.messgae_mod

        if return_type == SendType.send_all:  # 群发
            self.channelBox.groupSend(body=return_message)
        elif return_type == SendType.send_self:  # 私法
            self.send(json.dumps(return_message, ensure_ascii=False))

    def websocket_disconnect(self, message):
        self.channelBox.groupSend(body={
            "messge_mod": "UserExit"
        })
        UserSite().gaming = False  # 所有人游戏退出
        self.channelBox.delete(self)
        raise StopConsumer()

    def chat_message(self, message):
        print("群发中")
        text = message["body"]
        self.send(text)


class TestRunner(WebsocketConsumer):

    def websocket_connect(self, message):
        """
        客户端来向后端发送请求的时候 自动触发
        :param message:
        :return:
        """
        channel_box = ChannelBox()
        self.accept()

        handler = async_to_sync(channel_box.channel_layer.group_add)
        handler("inner", self.channel_name)

        print("Connect Success")

    def websocket_receive(self, message):
        """
        浏览器基于ws向后端发送数据，自动触发接受消息
        :param message:
        :return:
        """

        channel_box = ChannelBox()
        channel_box.groupSend({"value": "群发完毕", "New": 2}, "inner")
        print("接受到的数据", message)

        val = message.get("text")
        a = json.dumps({"你好啊": val}, ensure_ascii=False)

    def websocket_disconnect(self, message):
        """
        断开链接的时候触发
        :param message:
        :return:
        """

        raise StopConsumer()

    def chat_message(self, message):
        text = message["body"]
        self.send(text)
